package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import com.tencentcloudapi.vod.v20180717.models.MediaBasicInfo;
import com.tencentcloudapi.vod.v20180717.models.MediaInfo;
import com.tencentcloudapi.vod.v20180717.models.MediaMetaData;
import com.tencentcloudapi.vod.v20180717.models.WatermarkInput;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    //TODO
    private final Long userId = 1L;
    @Autowired
    private TrackInfoMapper trackInfoMapper;
    @Resource
    VodConstantProperties constantProperties;
    @Resource
    VodService vodService;
    @Resource
    TrackStatMapper trackStatMapper;

    /**
     * 音频上传
     *
     * @param file
     * @return
     */
    @SneakyThrows
    @Override
    public Object uploadTrack(MultipartFile file) {
        JSONObject jsonObject = new JSONObject();
        //将文件存储到本地临时目录
        String tempPath = UploadFileUtil.uploadTempPath(constantProperties.getTempPath(), file);
        //初始化一个客户端对象
        VodUploadClient vodUploadClient = new VodUploadClient(constantProperties.getSecretId(), constantProperties.getSecretKey());
        //构造上传请求对象
        VodUploadRequest vodUploadRequest = new VodUploadRequest();
        vodUploadRequest.setMediaFilePath(tempPath);
        //再将文件上传到腾讯云
        VodUploadResponse response = vodUploadClient.upload(constantProperties.getRegion(), vodUploadRequest);
        //解析文件唯一标识
        String fileId = response.getFileId();
        jsonObject.put("mediaFileId", fileId);
        //获取播放地址
        String mediaUrl = response.getMediaUrl();
        jsonObject.put("mediaUrl", mediaUrl);
        //返回
        return jsonObject;
    }

    /**
     * 音频上传
     *
     * @param trackInfoVo
     */
    @Override
    public void saveTrackInfo(TrackInfoVo trackInfoVo) {
        //排序初始化
        Integer orderNum = 1;
        //获取本次新增声音所属id
        Long albumId = trackInfoVo.getAlbumId();
        //查询专辑最后一条num
        TrackInfo trackInfo = getOne(new LambdaQueryWrapper<TrackInfo>()
                .eq(TrackInfo::getAlbumId, albumId)
                .orderByDesc(TrackInfo::getOrderNum)
                .last("limit 1"));
        if (trackInfo != null) {
            //不是一条声音
            orderNum = trackInfo.getOrderNum() + 1;

        }
        //声明do
        trackInfo = new TrackInfo();
        //属性转移
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        //补全数据
        trackInfo.setUserId(userId);
        trackInfo.setOrderNum(orderNum);
        //通过文件位唯一标识去腾讯云查询详细信息
        MediaInfo[] mediaInfos = vodService.getFileInfoByFileId(trackInfoVo.getMediaFileId());
        if (mediaInfos == null || mediaInfos.length <= 0) {
            throw new GuiguException(201, "保存音频失败，文件不存在");
        }
        MediaInfo mediaInfo = mediaInfos[0];
        //获取基础数据
        MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
        trackInfo.setMediaType(basicInfo.getType());
        //获取原信息
        MediaMetaData metaData = mediaInfo.getMetaData();
        trackInfo.setMediaSize(metaData.getSize());
        trackInfo.setMediaDuration(new BigDecimal(metaData.getDuration().toString()));
        trackInfo.setMediaFileId(trackInfoVo.getMediaFileId());
        trackInfo.setMediaUrl(basicInfo.getMediaUrl());
        //保存声音到数据库
        if (!save(trackInfo)) {
            throw new GuiguException(201, "保存声音失效");
        }
        //初始化统计数据
        initTrackStat(trackInfo.getId());
    }

    /**
     * 音频分页
     * @param page
     * @param size
     * @param trackInfoQuery
     * @return
     */
    @Override
    public Object findUserTrackPage(Integer page, Integer size, TrackInfoQuery trackInfoQuery) {
        trackInfoQuery.setUserId(userId);
        return trackInfoMapper.pageTrackInfoByQuery(new Page<>(page,size),trackInfoQuery);
    }

    /**
     * 删除
     * @param trackId
     * @return
     */
    @Override
    public void removeTrackInfo(Long trackId) {
        //查询条件
        LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getId, trackId).eq(TrackInfo::getUserId, userId);
        //查询声音
        TrackInfo trackInfo = getOne(wrapper);
        if (trackInfo == null){
            return;
        }
        //删除声音数据库
        if (!removeById(trackId)) {
            throw new GuiguException(201, "删除声音数据失败");
        }
        //删除声音的统计数据
        int delete = trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, trackId));
        if (delete <0) {
            throw new GuiguException(201,"删除统计数据失败");
        }
        //删除云点播文件
        vodService.removeFile(trackInfo.getMediaFileId());

    }

    @Override
    public Object getTrackInfo(Long trackId) {

        return getOne(new LambdaQueryWrapper<TrackInfo>()
                .eq(TrackInfo::getId, trackId)
                .eq(TrackInfo::getUserId, userId));
    }

    /**
     * 修改声音
     * @param trackId
     */
    @Override
    public void updateTrackInfo(Long trackId,TrackInfoVo trackInfoVo ){
        //查询声音数据
        LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getId, trackId).eq(TrackInfo::getUserId, userId);
        //查询声音
        TrackInfo trackInfo = getOne(wrapper);
        if (trackInfo == null) {
            return;
        }
        String mediaFileIdDb = trackInfo.getMediaFileId();
        BeanUtils.copyProperties(trackInfoVo, mediaFileIdDb);
        //判断声音是否改变
        String mediaFileIdNow = trackInfoVo.getMediaFileId();
        if (!mediaFileIdNow.equals(mediaFileIdDb)) {
            //删除旧的
            vodService.removeFile(mediaFileIdDb);
            //音频文件变化，查询新的音频
            MediaInfo[] mediaInfos = vodService.getFileInfoByFileId(mediaFileIdNow);
            if (mediaInfos==null||mediaInfos.length<=0){
                 throw new GuiguException(201, "保存新声音失败");
            }
            MediaInfo mediaInfo = mediaInfos[0];
            //获取基础数据
            MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
            trackInfo.setMediaType(basicInfo.getType());
            //获取原信息
            MediaMetaData metaData = mediaInfo.getMetaData();
            trackInfo.setMediaSize(metaData.getSize());
            trackInfo.setMediaDuration(new BigDecimal(metaData.getDuration().toString()));
            trackInfo.setMediaFileId(trackInfoVo.getMediaFileId());
            trackInfo.setMediaUrl(basicInfo.getMediaUrl());
        }
        //修改
        if (!updateById(trackInfo)) {
            throw new GuiguException(201, "修改音频失败");
        }

    }

    /**
     * 初始化统计数据
     *
     * @param trackId
     */
    private void initTrackStat(Long trackId) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatNum(0);
        //播放量
        trackStat.setStatType(SystemConstant.ALBUM_STAT_PLAY);
        trackStatMapper.insert(trackStat);
        //收藏量
        trackStat.setId(null);
        trackStat.setStatType(SystemConstant.ALBUM_STAT_SUBSCRIBE);
        trackStatMapper.insert(trackStat);
        //点赞量
        trackStat.setId(null);
        trackStat.setStatType(SystemConstant.ALBUM_STAT_BROWSE);
        trackStatMapper.insert(trackStat);
        //评论数
        trackStat.setId(null);
        trackStat.setStatType(SystemConstant.ALBUM_STAT_COMMENT);
        trackStatMapper.insert(trackStat);
    }
}
